home *** CD-ROM | disk | FTP | other *** search
- /*
- * MEGA-TRANS-WARP DRIVE
- *
- * By: Dan Moore and Dave Small. Copyright 1987, 1988
- *
- * This TSR goes in your AUTO folder. After it is run, any large access to
- * the floppy disk drive goes at twice the speed it used to (maybe more
- * on double sided drives). You'll notice it on big copies.
- *
- * 0.5: Found Atari's seek-with-verify is done on same-track accesses. Ugly.
- * This causes single sector reads to miss a complete spin. Ugly. Forced
- * us to call ROMs directly to bypass that seek. -dlm, dms
- *
- * 1: Original version -- there's a bug in it. Buffer problem. -- dlm
- *
- * 2: Found that we need to 0-base sector # before multiplying by 512 to
- * get buffer address, or we land 512 too far down. Added some
- * debug code to find out what was going on. -- dms
- *
- * 3: Changed for 9/10 sec disks.. also, gotta add 2 (modulus) if twistered.
- * I analyzed what happens on a twistered disk, and find that the change
- * is not really that bad (2 extra sectors spin by each spin). So, no
- * need to change it. Cleaned up, commented. -- dms
- *
- * Added TSR sign-in page.
- *
- * 4: Misc. clean up to produce the work of ART you are now examining!
- * Also added a check for the right cut of the TOS ROM. (It wouldn't
- * be nice to jump off to never never land.) -- dlm
- *
- * 5: 06/20/88 (1 year after above stuff) -- taught it about the "new"
- * (well new since we wrote this) blitter ROMs in the Megas. This
- * is the new improved Mega-Trans-Warp Drive for your ST. -- dms & dlm
- *
- * 5.1: 07/08/88 (2 weeks after last comment --- wow we can tell time)
- * finish fixing the mega rom version. -- dlm & dms
- */
-
- #include <portab.h>
- #include <osbind.h>
-
- /* misc defines */
- #define TRUE 1
- #define FALSE 0
- #define RETRY 0x00010000
- #define void /**/
-
- #define LOADADR 0 /* print load address, bigger code tho. */
-
- #define low8bits(x) ((x) & 0xff)
-
- #define puts(str) Cconws(str) /* I can remember puts, but Cconws? */
-
- /*
- * defines for OS version test
- */
- #define BUILDDATE 0x11201985L /* build date for current ROM */
- #define MEGDATE 0x04221987L /* build date for more current ROM */
- #define DATEADR 0x00fc0018L /* location of date in OS ROM */
-
- /*
- * Error codes
- */
- #define OK 0
- #define DRIVE_NOT_READY (-2)
- #define MEDIA_CHANGE (-14)
- #define BAD_SECTORS (-16)
-
- #define CRITICAL_RETRY 0x00010000L /* "retry" return code */
-
- /*
- * media change status
- */
- #define SAFE 0
- #define UNSURE 1
- #define CHANGED 2
-
- /* typedefs to make declarations easier */
- typedef LONG (*L_FUNC)(); /* pointer to function returning a long */
- typedef WORD (*W_FUNC)(); /* pointer to function retruning a word */
-
- /* misc. global work variables */
- L_FUNC sys_rwabs; /* old rwabs routine. */
- L_FUNC *rwvect = (L_FUNC *) 0x476; /* pointer to current rwabs */
- L_FUNC *critic = (L_FUNC *) 0x404L; /* system critical error handler */
-
- /*
- * We have to directly call ROM routines out of floprw, or recode them here.
- * We chose to call them.
- */
-
- #define old_chkm 0xfc1000L
- #define new_chkm 0xfc11e4L
-
- L_FUNC chkmedia; /* pointer to ROM routine */
-
- /*
- * BPB structure
- */
- struct bpb {
- WORD recsiz, /* physical sector size in bytes */
- clsiz, /* cluster size in sectors */
- clsizb, /* cluster size in bytes */
- rdlen, /* root directory length in sectors */
- fsiz, /* FAT size in sectors */
- fatrec, /* sector# of 1st sector of 2nd FAT */
- datrec, /* sector# of 1st data sector */
- numcl, /* number of data clusters on disk */
- bflags; /* various flags */
- };
-
- /*
- * "Device State Block"
- * as defined by us.
- * The DSB is used by drivers to hold a device's state.
- * Most devices require a pointer to this beastie as a parameter
- * in their calls.
- */
- struct dsb {
- struct bpb b; /* GEMDOS' BPB */
- WORD dntracks, /* #tracks (cylinders) on dev */
- dnsides, /* #sides per cylinder */
- dspc, /* #sectors/cylinder */
- dspt, /* #sectors/track */
- dhidden; /* #hidden tracks */
- char dserial[3]; /* 24-bit volume serial number */
- } *dsbtab;
-
- #define old_dsbtab 0x4dceL
- #define new_dsbtab 0x7570L
-
- /*
- * the following are misc control variables used by the ROM routines.
- * one reason we "stole" the ROM routines and variables is to avoid
- * having to rewrite the VBLANK routines that change some of these
- * variables. (The VBLANK routine checks for disk insertion/removal by
- * watching the write protect status of the disk. That's where media
- * "UNSURE" errors come from.)
- */
- WORD *fverify = (WORD *) 0x0444L; /* system floppy table */
- BYTE *diskmode = (BYTE *) 0x4db8L;
- BYTE *diskbuf = (BYTE *) 0x167aL;
- WORD *nflops = (WORD *) 0x04a6L; /* number of floppies (0-2) */
-
- #define old_diskm 0x4db8L
- #define new_diskm 0x755aL
-
- #define old_diskbuf 0x167aL
- #define new_diskbuf 0x16daL
-
- WORD all_cool; /* true means good ROM rev */
- WORD newer_roms; /* true for the new ROMs */
-
- /*
- * macros to handle selection of the correct floppy i/o patch routine
- * based on the rom version we are running under.
- * also set the ret value for the "outside" routine that calls us.
- */
- #define do_read(a,b,c,d,e,f,g) { \
- if (newer_roms) \
- ret = meg_floprd((a),(b),(c),(d),(e),(f),(g)); \
- else \
- ret = our_floprd((a),(b),(c),(d),(e),(f),(g)); \
- }
-
- #define do_write(a,b,c,d,e,f,g) { \
- if (newer_roms) \
- ret = meg_flopwr((a),(b),(c),(d),(e),(f),(g)); \
- else \
- ret = our_flopwr((a),(b),(c),(d),(e),(f),(g)); \
- }
-
- extern saveA4(), exit();
- asm {
- exit: ; just to fool the linker and prevent the inclusion
- ; of unneeded (and unwanted) library routines
-
- saveA4: dc.l 0 ; pointer to global variables
- ; in program segment so rwabs can get it
- }
-
-
- extern bytecpy();
- asm {
- ; bytecpy(source, dest)
- ; one byte at a time copy, for non-aligned moves. SLOW!!!!!!
- bytecpy:
- move.l #511, D0 ; count - 1
- movea.l 4(A7), A0 ; source
- movea.l 8(A7), A1 ; dest
-
- loop:
- move.b (A0)+, (A1)+ ; move a WHOLE byte (as opposed to a nybble)
- dbf D0, loop
-
- rts ; all done.
- }
-
- /*
- * Convert a low high (8086 style) number to high low (68K) style.
- */
- int swapint(loc)
- char *loc;
- {
- return (low8bits(*(loc+1)) << 8) | low8bits(*loc);
- }
-
- /*
- * due to a major stupidity in the ST BIOS, we have to clone the
- * first few lines of floprd & flopwr for our second calls. Otherwise
- * it proceeds to re-verify that the head is on the right track. This
- * makes us miss the next sector. It also means that all single
- * sector read/write calls take ONE rev for each sector!!!!!!!!!
- *
- * UGLY!!!! UGLY!!!! UGLY!!!!!
- *
- * our_floprd(buf, filler, devno, sectno, trackno, sideno, count)
- * our_flopwr(buf, filler, devno, sectno, trackno, sideno, count)
- *
- */
-
- /*
- * The following are hard addresses in the TOS ROM!
- *
- * You are NEVER supposed to do this. But since we know what we're
- * doing ....
- *
- * values for original 11/20/85 roms
- */
- #define change 0xfc1cbe
- #define floplock 0xfc1a34
- #define select 0xfc1c14
- #define go2track 0xfc1b7a
- #define setdmode 0xfc1cf6
- #define to_rom_r 0xfc15b4
- #define to_rom_w 0xfc16a8
- /*
- * values for blitter roms
- */
- #define m_change 0xfc1ebe
- #define m_floplock 0xfc1c48
- #define m_select 0xfc1e14
- #define m_go2track 0xfc1d7a
- #define m_setdmode 0xfc1ef6
- #define m_to_rom_r 0xfc1798
- #define m_to_rom_w 0xfc1884
-
- /*
- * declarations to allow inline asm outside of a func to work.
- */
- extern our_floprd(), our_flopwr(), meg_floprd(), meg_flopwr();
-
- /*
- * The commented out lines are the WHOLE reason this code is
- * duplicated here. If they weren't in the ROM or if track stepping
- * was handled intellegently this crap wouldn't be needed.
- *
- * These lines are from the floppy i/o code as previously published in
- * STart in Dave's track dumper article. (Issue #1)
- *
- * In order to keep things simple here we will supply two different
- * pairs of these routines. One for the ROM addresses in the old STs and
- * one for the new ones.
- */
- asm {
- our_floprd:
- jsr change ; test for disk change
- moveq #0xf5, D0 ; set default error#
- jsr floplock ; lock floppies, setup parameters
- jsr select ; select drive, setup registers
- ; bsr go2track ; seek appropriate track (UGLY! -- dlm)
- jmp to_rom_r ; and return to the REAL rom code. -- dlm
-
-
- meg_floprd:
- jsr m_change ; test for disk change
- moveq #0xf5, D0 ; set default error#
- jsr m_floplock ; lock floppies, setup parameters
- jsr m_select ; select drive, setup registers
- ; bsr go2track ; seek appropriate track (UGLY! -- dlm)
- jmp m_to_rom_r ; and return to the REAL rom code. -- dlm
-
-
-
- our_flopwr:
- jsr change ; check for disk swap
- moveq #0xf6,D0 ; set default error number
- jsr floplock ; lock floppies
-
- ;
- ; If the boot sector is written to,
- ; set the media change mode to "unsure".
- ; (Kludge, kludge, kludge....)
- ;
- move.w 0x9c6(A5),D0 ; sector 1
- subq #1,D0
- or.w 0x9c4(A5),D0 ; track 0
- or.w 0x9c8(A5),D0 ; side 0
- bne fwr1 ; if not boot sector, then OK
- moveq #2,D0 ; set media change mode to unsure
- jsr setdmode ; (boy, is this /ugly/)
-
- fwr1:
- jsr select ; select drive
- ; bsr go2track ; seek (no, THIS is ugly) -- dlm
-
- jmp to_rom_w ; back to the REAL rom code -- dlm
-
- meg_flopwr:
- jsr m_change ; check for disk swap
- moveq #0xf6,D0 ; set default error number
- jsr m_floplock ; lock floppies
-
- ;
- ; If the boot sector is written to,
- ; set the media change mode to "unsure".
- ; (Kludge, kludge, kludge....)
- ;
- move.w 0x9c6(A5),D0 ; sector 1
- subq #1,D0
- or.w 0x9c4(A5),D0 ; track 0
- or.w 0x9c8(A5),D0 ; side 0
- bne m_fwr1 ; if not boot sector, then OK
- moveq #2,D0 ; set media change mode to unsure
- jsr m_setdmode ; (boy, is this /ugly/)
-
- m_fwr1:
- jsr m_select ; select drive
- ; bsr m_go2track ; seek (no, THIS is ugly) -- dlm
-
- jmp m_to_rom_w ; back to the REAL rom code -- dlm
- }
-
- /*
- * The Trans-Warp Drive version of rwabs. It takes care of
- * all the work involved in the floppy i/o.
- */
- LONG
- trans_warp(rw, buf, count, recno, dev)
- LONG buf;
- WORD rw, count, recno, dev;
- {
- LONG ret;
- register struct dsb *p;
- register WORD track, side, sect, cnt;
- WORD oddflag; /*
- * indicates an oddbyte copy, requiring
- * a seperate buffer (floprd, flopwr only work
- * to a word aligned buffer), thus
- * indicates pre-write or post-read copy.
- */
- WORD modulus; /*
- * The # to divide the track by to find out
- * how to twist the readin process.
- */
- WORD last_track = -1; /*
- * The last track we read. We don't use a
- * read-with-seek if we are on same track,
- * else reads to other side of same disk
- * lose a spin.
- */
- LONG bf; /* working i/o buffer */
- WORD skewer, counter; /* starting sector & # to read on 2nd spin. */
-
- /* 9 sector skew data */
- static WORD skew[] = {1, 3, 5, 7}; /* start read sec */
- static WORD cnton2[] = { 0, 2, 4, 6}; /* count for 2nd rd, start at 1 */
- /* 10 sector skew data */
- static WORD skew10[] = {1, 3, 5, 7, 9}; /* which sec to start on */
- static WORD cnt10[] = { 0, 2, 4, 6, 8}; /* cnt for 2nd spin */
-
- /*
- * All this takes some explaining, so go look at the article, which is
- * why I WRITE these things, okay?
- */
-
- /* at this point the trap dispatcher has saved D3-D7/A3-A6 */
- asm {
- movea.l saveA4(PC), A4 ; Megamax global variable pointer
- }
-
- /* first see if this call is for us or not */
- if (dev >= 2) { /* Pass the call thru to the system rwabs routine. */
- return((*sys_rwabs)(rw, buf, count, recno, dev));
- }
-
- /* we are wanted. Dead or alive */
- if (!*nflops)
- return (DRIVE_NOT_READY); /* no disks (foolish person) */
-
- /*
- * If 'buf' is 0L, then set the media-change mode
- * on the dev to whatever 'count' is. This is a little known
- * hack to get rid of media changes. */
- if (!buf) {
- diskmode[dev] = count;
- return (OK);
- }
-
- /*
- * If 'rw' allows media-change checking, then
- * make sure the disk in the drive is the one we
- * really want there. If 'chkmedia' returns a
- * hard error, return that hard error. If 'chkmedia'
- * discovers a media change, return that.
- */
- if (rw < 2 && (ret = (long)(*chkmedia)(dev)) != 0) {
- if (ret == CHANGED)
- ret = MEDIA_CHANGE;
- return (ret); /* frankly my dear, I don't give a damn */
-
- /*
- * Pun Alert:
- * The preceding comment was a pun.
- * If you missed it, think of
- * Gone With the Wind.
- */
- }
-
- /* Skew table logic:
- *
- * 9-sector disks:
- * 0: 123456789 123456789 123456789 123456789 123456789 123456789 123456789
- * *********
- * 1: 123456789 123456789 123456789 123456789 123456789 123456789 123456789
- * **********
- * 2: 123456789 123456789 123456789 123456789 123456789 123456789 123456789
- * **********
- * 3: 123456789 123456789 123456789 123456789 123456789 123456789 123456789
- * *** ******
- * 4: 123456789 123456789 123456789 123456789 123456789 123456789 123456789
- * ********
- * 5: 123456789 123456789 123456789 123456789 123456789 123456789 123456789
- *
- * 0: read 1-9, no other read.
- * 1: read 3-9, then 1-2.
- * 2: read 5-9, then 1-4.
- * 3: read 7-9, then 1-6.
- * 4: read 1-9, no other read. (we drop an extra sector, but, big deal...)
- *
- * This info is in the skew and cnton2 arrays. Skew tells us the starting
- * sector for the primary read. cnton2 tells us how many sectors, starting
- * at 1, we read in the secondary read. If cnton2 is 0, then we have no
- * secondary read.
- *
- * 10 sector disks:
- *
- * 0: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * **********
- * 1: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * ******** **
- * 2: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * ****** ****
- * 3: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * **** ******
- * 4: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * ** ********
- * 5: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * **********
- *
- * 0: read 1-A, no second.
- * 1: read 3-A, then 1-2.
- * 2: read 5-A, then 1-4.
- * 3: read 7-A, then 1-6.
- * 4: read 9-A, then 1-8.
- * 5: read 1-A, no second.
- *
- * The skew10[] and cnt10[] arrays hold THIS information. We pick between
- * these arrays, and whether to go by 5 (10 secs) or 4 (9 secs), based on
- * info DOS gives us (p->dspt).
- *
- *
- * 10 sector Twistered Disks, assuming normal 10-sec Transwarp done.
- *
- * 0: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * **********
- * 1: 9A12345678 9A12345678 9A12345678 9A12345678 9A12345678 9A12345678 9A12345678
- * ****** ****
- * 2: 789A123456 789A123456 789A123456 789A123456 789A123456 789A123456 789A123456
- * ** ********
- * 3: 56789A1234 56789A1234 56789A1234 56789A1234 56789A1234 56789A1234 56789A1234
- * ******** **
- * 4: 3456789A12 56789A1234 56789A1234 56789A1234 56789A1234 56789A1234 56789A1234
- * ***********
- * 5: 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A 123456789A
- * --> 1-A
- *
- * Hence, it just slows down Twister a bit (2 secs more per) - gives it
- * 4 sectors to resync as opposed to 2, which is the minimum.
- *
- * Net effect is that twistered disks will run slightly slower under
- * Transwarp than by themselves...but at least it isn't a large loss.
- *
- * Besides Twistered disks still run fast without Transwarp.
- */
-
- p = &dsbtab[dev]; /* pointer to drive info table */
-
- oddflag = ((buf & 1) == 1); /* odd address transfer? (slow if it is) */
-
- if (!p->dspc) /* "cannot happen" */
- p->dspt = p->dspc = 9;
-
- /*
- * Read or write sectors.
- * Optimize for multi-sector transfers
- * (as much of a track as possible):
- */
- while (count) {
- bf = (oddflag ? (long) diskbuf : buf); /* choose a buffer */
-
- track = recno / p->dspc; /* compute track# */
-
- sect = recno % p->dspc; /* compute sector# */
-
- if (sect < p->dspt)
- side = 0; /* single-sided media */
- else { /* two-sided media */
- side = 1;
- sect -= p->dspt;
- }
-
- if (oddflag)
- cnt = 1; /* unaligned: read 1 sector */
- else if ((p->dspt - sect) < count)
- cnt = p->dspt - sect; /* rest of track */
- else
- cnt = count; /* part of track */
-
- ++sect; /* physical sector number */
-
- do { /* loop while there is an error */
- if (rw & 1) { /* write */
- if (bf != buf) /* if odd aligned, get into even buffer. */
- bytecpy(buf, bf);
-
- if (cnt == p->dspt && sect == 1) { /* whole track? */
-
- /* Yup. So, pick modulus. 9 sector disks: 4. 10 sector disks: 5. */
-
- modulus = track % (p->dspt == 9 ? 4 : 5);
-
- /*
- * Pick off, for this track, the sector to start
- * reading at in the primary pass, and the sector
- * to read up to in the secondary pass.
- */
-
- if (p->dspt == 9) { /* 9 sec */
- skewer = skew[modulus];
- counter = cnton2[modulus];
- }
- else { /* 10 sec */
- skewer = skew10[modulus];
- counter = cnt10[modulus];
- }
-
- /*
- * it also slows down from side to side on the
- * same track since Flopwr re-verfies even THEN!
- *
- * our smart code doesn't do a seek if we are on the
- * same track (already verified).
- */
-
- if (last_track == track) { /* track hasn't changed */
- do_write(bf + (skewer-1) * 512, 0L, dev, skewer, /* no seek */
- track, side, p->dspt - skewer + 1);
- }
- else {
- ret = Flopwr(bf + (skewer-1) * 512, 0L, dev, skewer, /* yes seek */
- track, side, p->dspt - skewer + 1);
- }
-
- if (ret == 0 && counter) /* two writes? */
- do_write(bf, 0L, dev, 1, track, side, counter); /* no seek */
- }
- else { /* partial track */
- ret = Flopwr(bf, 0L, dev, sect, track, side, cnt);
- }
-
- last_track = track; /* save it for next time through */
-
- /*
- * This handles the $%^$% read-after-write verify.
- * Should just ditch the %^&$%^& thing.
- */
-
- if (!ret && *fverify) { /* verify */
- ret = Flopver(diskbuf, 0L, dev, sect, track, side, cnt);
- if (!ret && swapint(diskbuf))
- ret = BAD_SECTORS;
- }
- } /* end of write code */
- else { /* read */
- if (cnt == p->dspt && sect == 1) { /* whole track? */
- modulus = track % (p->dspt == 9 ? 4 : 5);
-
- if (p->dspt == 9) {
- skewer = skew[modulus];
- counter = cnton2[modulus];
- }
- else {
- skewer = skew10[modulus];
- counter = cnt10[modulus];
- }
-
- /* see the comment on flopwr above */
-
- if (last_track == track) { /* probly second side read */
- do_read(bf + (skewer-1) * 512, 0L, dev, skewer, /* no seek*/
- track, side, p->dspt - skewer + 1);
- }
- else {
- ret = Floprd(bf + (skewer-1) * 512, 0L, dev, skewer, /* yes seek */
- track, side, p->dspt - skewer + 1);
- }
-
- if (ret == 0 && counter) { /* two reads? */
- do_read(bf, 0L, dev, 1, track, side, counter);/* no seek */
- }
- }
- else { /* normal read */
- ret = Floprd(bf, 0L, dev, sect, track, side, cnt); /* seek */
- }
-
- last_track = track; /* save current track */
-
- if (bf != buf) /* unaligned? */
- bytecpy(bf, buf);
- } /* end of read code */
-
- /*
- * If an error has occured pass the code thru to
- * the critical error handler. (Normally this is
- * the cute GEM alert message that says RETRY or CANCEL.)
- */
- if (ret < 0) {
- ret = (**critic)((WORD)ret, dev);
- if (rw < 2 && ret == CRITICAL_RETRY && (*chkmedia)(dev) == CHANGED)
- ret = MEDIA_CHANGE;
- last_track = 99; /* force a real seek next time */
- }
- } while (ret == CRITICAL_RETRY);
-
- if (ret < 0)
- return (ret);
-
- buf += ((long)cnt << 9); /* advance DMA pointer */
- recno += cnt; /* bump record number */
- count -= cnt; /* decrement count */
- }
-
- return (OK);
- }
-
- void
- super_stuff()
- /*
- * read the default sysrwabs vector; store it; plug in our new one.
- *
- * also make sure we get real resets instead of fake ones and
- * disable write with verify. other programs (DAs and TSRs) may already
- * do that, but it doesn't hurt to be sure.
- *
- * And finally, check the build date of the OS ROMs. We don't want to
- * go jumping off to never-never land do we.
- */
- {
- asm {
- /* do this stuff always */
- clr.w 0x444 ; flopver
- clr.l 0x420 ; memvalid
- clr.l 0x43a ; memval2
-
- cmpi.l #BUILDDATE, DATEADR
- beq old_rom
-
- cmpi.l #MEGDATE, DATEADR
- beq new_rom
-
- clr.w all_cool(A4) ; wrong ROM! Oh s***!
- bra bad_rom
-
- }
-
- old_rom:
- chkmedia = (L_FUNC) old_chkm;
- dsbtab = (struct dsb *) old_dsbtab;
- diskmode = (BYTE *) old_diskm;
- diskbuf = (BYTE *) old_diskbuf;
- newer_roms = FALSE;
- goto good_rom;
-
- new_rom:
- chkmedia = (L_FUNC) new_chkm;
- dsbtab = (struct dsb *) new_dsbtab;
- diskmode = (BYTE *) new_diskm;
- diskbuf = (BYTE *) new_diskbuf;
- newer_roms = TRUE;
-
- /* falls thru here */
-
- /* aaaaaaaaaaaaahhhhhhhhhhhhhhhhhh!!!!! */
-
- /* S P L A T !!!!!! */
-
- good_rom:
-
- /* hook up the vectors to the new code */
-
-
- /* be sure to use REALLY strong wire in the hook ups */
-
- sys_rwabs = *rwvect;
- *rwvect = trans_warp;
- all_cool = TRUE;
-
- bad_rom: ;
- }
-
- /*
- * base page data. We need this to calculcate amount to keep resident.
- */
- #define codelen 12 /* Code segment length */
- #define datalen 20 /* Data segment length */
- #define bsslen 28 /* Bss segment length */
- extern char *_base; /* pointer to base page */
-
- main()
- {
- #if LOADADR
- LONG start_l, end_l; /* passed from base page, in assy, to C for printf */
-
- asm {
- movea.l _base(A4), A0 ; get base page indexes addr
- move.l A0, start_l(A6) ; save start of this code to disp
- move.l A0, D0 ; set start
- add.l codelen(A0),D0
- add.l datalen(A0),D0
- add.l bsslen(A0),D0
- add.l #256, D0 ; D0=basepage+textlen+datalen+bsslen
- move.l D0,end_l(A6) ; save end of this code to disp
- }
- #endif
-
-
- /*
- * first get the base address for the global variables so our rwabs can
- * use them.
- *
- * this is just about the only disadvantage to using Megamax for
- * this kind of stuff. And it is pretty trivial to get around.
- *
- */
- asm {
- lea saveA4(PC), A0
- move.l A4, (A0)
- }
-
- /*
- * find the current rwabs routine and do other super stuff
- */
- Supexec(super_stuff);
-
- /*
- * now lets see if all is cool with the ROM. If not say so and
- * run away to mommy.
- */
- if (!all_cool) {
- puts("Trans-Warp Drive not loaded.\r\nWrong TOS ROM installed.\r\n");
- Pterm(1); /* back to mother */
- }
-
- /*
- *
- * Will tonight's mystory guest please sign in ...
- */
- puts("\r\n**********************************************\r\n");
- puts("* *\r\n");
- puts("* Trans-Warp Drive, Version 5.10 *\r\n");
- puts("* Copyright 1987,1988 Dan Moore & Dave Small *\r\n");
- puts("* New, Improved and Mega Compatible!!!! *\r\n");
- puts("* Resets foxed. Floppy verify off. *\r\n");
- puts("* *\r\n");
- #if LOADADR
- puts("* RAM locations used: *\r\n");
- printf("* Start: $%06lx End: $%06lx *\n",start_l,end_l);
- #endif
- puts("**********************************************\r\n");
-
-
- /*
- * do a ptermres to return to system. We pass it the # of
- * bytes we wanna retain, so add up our usage, add 256 for the
- * base page, pray, and do it.
- */
-
- asm {
- movea.l _base(A4), A0
- move.l codelen(A0), D0
- add.l datalen(A0), D0
- add.l bsslen(A0), D0
- add.l #256, D0 ; D0=basepage+textlen+datalen+bsslen
-
- /* Actual ptermres (absolutely amazing, a genuine ptermres!) */
- move.w #0, -(A7) ; returned status (ok)
- move.l D0, -(A7) ; keep this # of bytes
- move.w #0x31, -(A7) ; ptermres command
- trap #1 ; call gemdos
- }
- }
-